<template>
  <div class="ranking-container">
    <div class="back-link">
      <el-button 
        link 
        type="primary"
        @click="goBack"
        :icon="ArrowLeft"
      >
        返回竞赛详情
      </el-button>
    </div>

    <div v-if="loading" class="loading-container">
      <el-skeleton :rows="10" animated />
    </div>

    <div v-else class="ranking-content">
      <el-card class="ranking-card" shadow="hover">
        <template #header>
          <div class="card-header">
            <h2>{{ contestTitle }} - 实时排名</h2>
            <el-tag v-if="contestStatus === 1" type="success" effect="light" round>进行中</el-tag>
            <el-tag v-else type="info" effect="plain" round>已结束</el-tag>
          </div>
        </template>

        <div class="ranking-info">
          <p>
            <el-icon><Timer /></el-icon>
            <span>更新时间: {{ formatDateTime(lastUpdateTime) }}</span>
            <el-button type="primary" link @click="fetchRankingData">
              <el-icon><Refresh /></el-icon>
              刷新
            </el-button>
          </p>
        </div>

        <el-table
          :data="rankingData"
          style="width: 100%"
          :row-class-name="tableRowClassName"
          v-loading="tableLoading"
        >
          <el-table-column
            type="index"
            label="排名"
            width="80"
            align="center"
          >
            <template #default="scope">
              <div class="rank-number" :class="getRankClass(scope.$index)">
                {{ scope.$index + 1 }}
              </div>
            </template>
          </el-table-column>
          
          <el-table-column prop="nickname" label="选手" min-width="150">
            <template #default="scope">
              <div class="participant">
                <el-avatar :size="30" :src="scope.row.avatar">
                  {{ scope.row.nickname ? scope.row.nickname.substring(0, 1) : 'U' }}
                </el-avatar>
                <span>{{ scope.row.nickname }}</span>
              </div>
            </template>
          </el-table-column>

          <el-table-column prop="totalScore" label="得分" width="100" sortable align="center" />
          
          <el-table-column prop="correctCount" label="答对题数" width="100" align="center" />
          
          <el-table-column prop="avgTime" label="平均用时" align="center">
            <template #default="scope">
              {{ formatTime(scope.row.avgTime) }}
            </template>
          </el-table-column>
          
          <el-table-column label="证书" width="100" align="center">
            <template #default="scope">
              <el-tag 
                v-if="hasCertificate(scope.row.rank)" 
                type="success"
                effect="light"
                size="small"
              >
                已获取
              </el-tag>
              <span v-else>-</span>
            </template>
          </el-table-column>
        </el-table>
        
        <div v-if="rankingData.length === 0 && !tableLoading" class="empty-data">
          <el-empty description="暂无排名数据" />
        </div>
        
        <div class="pagination-container">
          <el-pagination
            v-model:current-page="currentPage"
            v-model:page-size="pageSize"
            :page-sizes="[10, 20, 50]"
            :total="total"
            layout="total, sizes, prev, pager, next"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
            background
            hide-on-single-page
          />
        </div>
      </el-card>

      <!-- 个人成绩卡片 -->
      <el-card v-if="personalRank" class="personal-card" shadow="hover">
        <template #header>
          <div class="card-header">
            <h3>我的成绩</h3>
          </div>
        </template>
        
        <div class="personal-info">
          <div class="info-row">
            <div class="info-label">当前排名:</div>
            <div class="info-value rank">{{ personalRank.rank }}</div>
          </div>
          <div class="info-row">
            <div class="info-label">总分:</div>
            <div class="info-value score">{{ personalRank.totalScore }}</div>
          </div>
          <div class="info-row">
            <div class="info-label">答对题数:</div>
            <div class="info-value">{{ personalRank.correctCount }}</div>
          </div>
          <div class="info-row">
            <div class="info-label">平均用时:</div>
            <div class="info-value">{{ formatTime(personalRank.avgTime) }}</div>
          </div>
          <div class="info-row" v-if="hasCertificate(personalRank.rank)">
            <div class="info-label">证书:</div>
            <div class="info-value">
              <el-button type="success" size="small" @click="viewCertificate" round>
                预览证书
              </el-button>
              <el-button type="primary" size="small" @click="downloadMyCertificate" round style="margin-left: 10px;">
                下载证书
              </el-button>
            </div>
          </div>
        </div>
      </el-card>

      <!-- 证书预览对话框 -->
      <el-dialog v-model="dialogVisible" title="证书预览" width="60%" center>
        <div style="text-align: center;">
          <img :src="currentCertificateUrl" alt="证书预览" style="max-width: 100%; max-height: 70vh;"/>
        </div>
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="dialogVisible = false">关闭</el-button>
            <el-button type="primary" @click="downloadCertificateFromDialog">下载</el-button>
          </span>
        </template>
      </el-dialog>

    </div>
  </div>
</template>

<script>
import { ref, onMounted, onUnmounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { getContestDetail, getContestRanking } from '@/api/contest'
import { getMyCertificateForContest } from '@/api/certificate'
import { ArrowLeft, Timer, Refresh } from '@element-plus/icons-vue'

export default {
  name: 'ContestRanking',
  components: {
    ArrowLeft,
    Timer,
    Refresh
  },
  setup() {
    const route = useRoute()
    const router = useRouter()
    const contestId = ref(parseInt(route.params.id))
    const contestTitle = ref('')
    const contestStatus = ref(0)
    const certificateEnabled = ref(false)
    const certificateCount = ref(3)
    const loading = ref(true)
    const tableLoading = ref(false)
    const lastUpdateTime = ref(new Date())
    const rankingData = ref([])
    const currentPage = ref(1)
    const pageSize = ref(10)
    const total = ref(0)
    const personalRank = ref(null)

    const dialogVisible = ref(false)
    const currentCertificateUrl = ref('')
    const currentCertificateToDownload = ref(null)

    const apiBaseUrl = process.env.VUE_APP_API_BASE_URL || '';

    const fetchContestInfo = async () => {
      loading.value = true
      try {
        const res = await getContestDetail(contestId.value)
        contestTitle.value = res.data.title
        contestStatus.value = res.data.status
        certificateEnabled.value = res.data.certificateEnabled
        certificateCount.value = res.data.certificateCount
      } catch (error) {
        ElMessage.error('获取竞赛信息失败')
        console.error(error)
      } finally {
        loading.value = false
      }
    }

    const fetchRankingData = async () => {
      tableLoading.value = true
      try {
        const params = {
          page: currentPage.value,
          size: pageSize.value
        }
        const res = await getContestRanking(contestId.value, params)
        rankingData.value = res.data.records
        total.value = res.data.total
        lastUpdateTime.value = new Date()
        
        const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}')
        if (userInfo.id) {
          personalRank.value = res.data.personal || null
        }
      } catch (error) {
        ElMessage.error('获取排名数据失败')
        console.error(error)
      } finally {
        tableLoading.value = false
      }
    }

    const findMyCertificateForThisContest = async () => {
      console.log("[ContestRanking] findMyCertificateForThisContest called for contestId:", contestId.value);
      if (!contestId.value) {
        console.error("[ContestRanking] contestId is not available.");
        ElMessage.error('竞赛ID无效');
        return null;
      }
      try {
        // Call the new API that fetches certificate for a specific contest
        const res = await getMyCertificateForContest(contestId.value); 
        console.log("[ContestRanking] getMyCertificateForContest response:", res);

        // The response data should now be a single certificate object or null
        if (res.code === 200) { 
          // res.data might be null if no certificate, which is a valid success case
          const cert = res.data; 
          console.log("[ContestRanking] Certificate directly from API:", cert);
          return cert; // cert can be null here
        } else {
          ElMessage.error(res.message || '获取我的证书失败');
          console.error("[ContestRanking] Failed to get certificate:", res.message);
          return null;
        }
      } catch (error) {
        ElMessage.error('查找证书时出错');
        console.error("[ContestRanking] Error in findMyCertificateForThisContest:", error);
        return null;
      }
    };

    const viewCertificate = async () => {
      console.log("[ContestRanking] viewCertificate called");
      const cert = await findMyCertificateForThisContest();
      console.log("[ContestRanking] Cert found for view:", JSON.parse(JSON.stringify(cert || {})));

      if (cert && cert.downloadUrl) { // cert might be null, so check it first
        console.log("[ContestRanking] Cert and downloadUrl are valid for viewing.");
        currentCertificateUrl.value = apiBaseUrl + cert.downloadUrl;
        console.log("[ContestRanking] currentCertificateUrl (for dialog img src):", currentCertificateUrl.value);
        currentCertificateToDownload.value = cert; 
        dialogVisible.value = true;
        console.log("[ContestRanking] dialogVisible set to true. Dialog should appear.");
      } else {
        console.warn("[ContestRanking] Cert or downloadUrl not found/invalid for viewing. Cert:", JSON.parse(JSON.stringify(cert || {})), "Download URL:", cert ? cert.downloadUrl : 'N/A');
        // Check if the API returned a specific message for no certificate
        // The controller now returns a success with null data and a message for no certificate.
        // So, if cert is null, it implies no certificate.
        if (!cert) {
            ElMessage.info('您在此竞赛中没有符合条件的证书。');
        } else {
            ElMessage.warning('证书信息不完整，无法预览。');
        }
      }
    }

    const downloadMyCertificate = async () => {
      console.log("[ContestRanking] downloadMyCertificate called");
      const cert = await findMyCertificateForThisContest();
      console.log("[ContestRanking] Cert found for download:", JSON.parse(JSON.stringify(cert || {})));

      if (cert && cert.id) { // cert might be null
        console.log("[ContestRanking] Cert and id are valid for download. ID:", cert.id, "Number from cert object:", cert.certificateNumber);
        const filenamePart = cert.certificateNumber || `certificate-${cert.id}`;
        downloadCertificateFile(cert.id, filenamePart);
      } else {
        console.warn("[ContestRanking] Cert or id not found/invalid for download. Cert:", JSON.parse(JSON.stringify(cert || {})), "ID:", cert ? cert.id : 'N/A');
        if (!cert) {
            ElMessage.info('您在此竞赛中没有符合条件的证书，无法下载。');
        } else {
            ElMessage.warning('证书信息不完整，无法下载。');
        }
      }
    };
    
    const downloadCertificateFromDialog = () => {
      if (currentCertificateToDownload.value && currentCertificateToDownload.value.id) {
        downloadCertificateFile(currentCertificateToDownload.value.id, currentCertificateToDownload.value.certificateNumber || `certificate-${currentCertificateToDownload.value.id}`);
        dialogVisible.value = false; 
      } else {
        ElMessage.error('无法下载证书，信息不完整。');
      }
    };

    const downloadCertificateFile = async (certificateId, certificateNumber) => {
      try {
        const token = localStorage.getItem('token');
        if (!token) {
          ElMessage.error('用户未登录，无法下载证书');
          return;
        }
        const downloadUrl = `${apiBaseUrl}/api/certificates/download/${certificateId}`;
        
        const response = await fetch(downloadUrl, {
          method: 'GET',
          headers: {
            'Authorization': `Bearer ${token}`
          }
        });

        if (response.ok) {
          const blob = await response.blob();
          const link = document.createElement('a');
          link.href = URL.createObjectURL(blob);
          const filename = response.headers.get('content-disposition')?.split('filename=')[1]?.replace(/"/g, '') || `${certificateNumber}.png`;
          link.download = filename;
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link);
          URL.revokeObjectURL(link.href);
          ElMessage.success('证书开始下载');
        } else {
          const errorData = await response.json().catch(() => ({ message: '下载失败，无法解析错误信息' }));
          ElMessage.error(errorData.message || `下载证书失败: ${response.statusText}`);
        }
      } catch (error) {
        console.error('下载证书错误:', error);
        ElMessage.error('下载证书时发生网络错误');
      }
    };

    const handleSizeChange = (size) => {
      pageSize.value = size
      currentPage.value = 1
      fetchRankingData()
    }

    const handleCurrentChange = (page) => {
      currentPage.value = page
      fetchRankingData()
    }

    const getRankClass = (index) => {
      if (index === 0) return 'rank-first'
      if (index === 1) return 'rank-second'
      if (index === 2) return 'rank-third'
      return ''
    }

    const tableRowClassName = ({ row }) => {
      const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}')
      if (userInfo.id && row.userId === userInfo.id) {
        return 'current-user-row'
      }
      return ''
    }

    const hasCertificate = (rank) => { 
      return certificateEnabled.value && rank && rank > 0 && rank <= certificateCount.value;
    }

    const goBack = () => {
      router.push(`/contest/detail/${contestId.value}`)
    }

    const formatTime = (seconds) => {
      if (!seconds && seconds !== 0) return '-'
      const min = Math.floor(seconds / 60)
      const sec = Math.round(seconds % 60) 
      return `${min.toString().padStart(2, '0')}:${sec.toString().padStart(2, '0')}`
    }

    const formatDateTime = (date) => {
      if (!date) return '-'
      const d = new Date(date) 
      return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')} ${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}:${String(d.getSeconds()).padStart(2, '0')}`
    }
    
    let refreshTimer = null;

    onMounted(() => {
      fetchContestInfo().then(() => {
        fetchRankingData(); 
        
        if (contestStatus.value === 1) {
          refreshTimer = setInterval(() => {
            if (contestStatus.value === 1) { 
               fetchRankingData();
            } else {
              clearInterval(refreshTimer); 
            }
          }, 30000);
        }
      });
    });

    onUnmounted(() => {
      if (refreshTimer) {
        clearInterval(refreshTimer);
      }
    });

    return {
      contestId,
      contestTitle,
      contestStatus,
      certificateEnabled,
      certificateCount,
      loading,
      tableLoading,
      lastUpdateTime,
      rankingData,
      currentPage,
      pageSize,
      total,
      personalRank,
      ArrowLeft,
      Timer, 
      Refresh, 
      
      fetchRankingData,
      handleSizeChange,
      handleCurrentChange,
      getRankClass,
      tableRowClassName,
      hasCertificate,
      viewCertificate,
      downloadMyCertificate,
      goBack,
      formatTime,
      formatDateTime,

      dialogVisible,
      currentCertificateUrl,
      downloadCertificateFromDialog,
    }
  }
}
</script>

<style lang="scss" scoped>
.ranking-container {
  padding: 20px;
  
  .back-link {
    margin-bottom: 20px;
  }
  
  .loading-container {
    padding: 40px 0;
  }
  
  .ranking-content {
    display: flex;
    flex-direction: column;
    gap: 20px;
  }
  
  .ranking-card, .personal-card {
    border-radius: 12px;
    
    .card-header {
      display: flex;
      align-items: center;
      gap: 15px;
      
      h2, h3 {
        margin: 0;
        color: #2c3e50;
      }
    }
    
    .ranking-info {
      margin-bottom: 20px;
      
      p {
        display: flex;
        align-items: center;
        gap: 8px;
        color: #606266;
        font-size: 14px;
        margin: 0;
      }
    }
    
    .empty-data {
      padding: 30px 0;
    }
    
    .pagination-container {
      margin-top: 20px;
      display: flex;
      justify-content: center;
    }
    
    :deep(.el-table) {
      border-radius: 8px;
      overflow: hidden;
      
      .el-table__header th {
        background-color: #f5f7fa;
        color: #606266;
        font-weight: 600;
      }
      
      .current-user-row {
        background-color: rgba(64, 158, 255, 0.1);
      }
      
      .rank-number {
        display: inline-flex;
        justify-content: center;
        align-items: center;
        width: 30px;
        height: 30px;
        border-radius: 50%;
        font-weight: bold;
        
        &.rank-first {
          background-color: #f7c427;
          color: white;
        }
        
        &.rank-second {
          background-color: #c0c0c0;
          color: white;
        }
        
        &.rank-third {
          background-color: #cd7f32;
          color: white;
        }
      }
      
      .participant {
        display: flex;
        align-items: center;
        gap: 10px;
      }
    }
  }
  
  .personal-card {
    .personal-info {
      padding: 0 10px;
      
      .info-row {
        display: flex;
        padding: 12px 0;
        border-bottom: 1px dashed #ebeef5;
        
        &:last-child {
          border-bottom: none;
        }
        
        .info-label {
          width: 100px;
          color: #909399;
        }
        
        .info-value {
          flex: 1;
          color: #606266;
          font-weight: 500;
          
          &.rank {
            color: #409eff;
            font-size: 18px;
          }
          
          &.score {
            color: #67c23a;
            font-size: 18px;
          }
        }
      }
    }
  }
}
</style> 